#include <stdio.h>
#include <stdlib.h>
#include <sys/file.h>
#include <stdarg.h>

#include "app_gattdb.h"
#include "sl_bt_api.h"
#include "sli_bt_api.h"
#include "sl_bt_ncp_host.h"
#include "cmd_rsp_evt_name_table.h"
#include "gk.h"
#include "uart.h"

extern int b_status;
static stGk_t gk = {0};
static stGk_evt_t gk_evt = {0};
static int battery = 1;

static int gk_rsp_evt_handler(sl_bt_msg_t *pkt);
static uint8_t advertising_set_handle = 0xff;
static char g_bt_addr[6] = {};
static int connection = -1;
//static stSchduleTask_t gk_sp_task;
//static stSchduleTask_t gk_sd_task;
// Handle for dynamic GATT Database session.
uint16_t gattdb_session;

static void gk_log(int priority, const char* a_format,...);

int gk_get_fd() {
	return uartGetFd();
}

int gk_loop() {
	sl_bt_msg_t evt;
	sl_status_t status = sl_bt_pop_event(&evt);
	if(status != SL_STATUS_OK){
		return -1;
	}
	gk_rsp_evt_handler(&evt);
	return 0;
}

void gk_uart_write(uint32_t len, uint8_t *data) {
	uartTx(len, data);
}

int32_t gk_uart_read(uint32_t len, uint8_t *data) {

	return uartRx(len, data);
}

int32_t gk_uart_peek(void) {

	return uartRxPeek();
}

int gk_init() {
	sl_bt_api_initialize_nonblock(gk_uart_write, gk_uart_read, gk_uart_peek);
	return 0;
}

int gk_set_mac(char* mac)
{
	memcpy(gk.u_mac, mac, sizeof(gk.u_mac));
	return 0;
}

int gk_open(char *dev, int buad) {
	gk.buad = buad;
	strcpy(gk.dev, dev);
	
	gk_log(GK_LOG_INFO,"Init Dev:%s, Buad:%d", gk.dev, gk.buad);
	int flowcontrol = 0;
	int ret = uartOpen(gk.dev, gk.buad, flowcontrol, 100);
	if (ret < 0) {
		gk_log(GK_LOG_WARNING,"Init Failed: %d", ret);
		return -1;
	}
	return 0;
}

int gk_close() {
	return uartClose();
}

static void gk_sd_start_adv_func() {
	gk_log(GK_LOG_INFO," ");
	sl_status_t sc;/*sl_bt_advertiser_user_data sl_bt_advertiser_general_discoverable*/
	sc = sl_bt_advertiser_start(advertising_set_handle, sl_bt_advertiser_user_data, sl_bt_advertiser_connectable_scannable);
	gk_log(GK_LOG_INFO,"start adv cmd result %u ", sc);
}

/**************************************************************************//**
 * Initialize GATT database dynamically.
 *****************************************************************************/
static void initialize_gatt_database(void)
{
  // New session
  sl_bt_gattdb_new_session(&gattdb_session);

}

static void gk_sd_set_adv_timeing_func() {
	gk_log(GK_LOG_INFO," ");
	sl_status_t sc;
	sc = sl_bt_advertiser_set_timing(advertising_set_handle, 160, 160, 0, 0);
	gk_log(GK_LOG_INFO,"set timming result %u", sc);
	usleep(20000);
	//schedue_add(&gk_sd_task, 20, gk_sd_start_adv_func, 0);
	gk_sd_start_adv_func();
}

static void gk_sd_set_adv_rsp_func() {
	gk_log(GK_LOG_INFO," ");
	sl_status_t sc;

	char serialno[] = "00000000000";
	uint8_t sn_len = strlen(serialno);
	uint8_t bcnBeaconAdvRspData[32] = {0};
	bcnBeaconAdvRspData[0] = (sn_len + 1)&0xff;
	bcnBeaconAdvRspData[1] = 0x09;
	memcpy(&bcnBeaconAdvRspData[2], serialno, sn_len);
	if (gk.bcnBeaconAdvRspDataLength > 0) {
		sc = sl_bt_advertiser_set_data(advertising_set_handle, 1, gk.bcnBeaconAdvRspDataLength, gk.bcnBeaconAdvRspData);
	} else {
		sc = sl_bt_advertiser_set_data(advertising_set_handle, 1, sn_len + 2, bcnBeaconAdvRspData);
	}
	gk_log(GK_LOG_INFO,"set rsp data result %u", sc);
		usleep(20000);
	//schedue_add(&gk_sd_task, 20, gk_sd_set_adv_timeing_func, 0);
	gk_sd_set_adv_timeing_func();
}

static void gk_sd_set_adv_func(char *bt_addr) {
	strcpy(g_bt_addr, bt_addr);
	// Pad and reverse unique ID to get System ID.
	characteristics[SYSTEM_ID].value[0] = bt_addr[5];
	characteristics[SYSTEM_ID].value[1] = bt_addr[4];
	characteristics[SYSTEM_ID].value[2] = bt_addr[3];
	characteristics[SYSTEM_ID].value[3] = 0xFF;
	characteristics[SYSTEM_ID].value[4] = 0xFE;
	characteristics[SYSTEM_ID].value[5] = bt_addr[2];
	characteristics[SYSTEM_ID].value[6] = bt_addr[1];
	characteristics[SYSTEM_ID].value[7] = bt_addr[0];

	// Initialize GATT database dynamically.
	initialize_gatt_database();
}

static int  gk_sd_get_bt_address(void *arg){
	bd_addr bt_mac = {};
	uint8_t type;
	sl_bt_system_get_identity_address(&bt_mac, &type);

	return 0;
}

int gk_advertiser_start() {
	gk_log(GK_LOG_INFO," ");
	sl_bt_system_reset(sl_bt_system_boot_mode_normal);

	return 0;
}


int gk_advertiser_stop() {
	if(0xff != advertising_set_handle){
		sl_bt_advertiser_stop(advertising_set_handle);
	}
	return 0;
}

int gk_hello() {
	sl_bt_system_hello();
	return 0;
}

int gk_heartbeat() {
	sl_bt_system_hello();
	return 0;
}

void gk_log(int priority, const char* a_format,...) {

	char s[1024];
	if (gk_evt.on_log != NULL) {
		va_list va;
		va_start(va, a_format);
		vsnprintf(s, sizeof(s), a_format, va);
		va_end(va);

		s[1023] = '\0';
		gk_evt.on_log(priority, s);
	}
}

int gk_server_notify(char *data, int len) {
	gk_log(GK_LOG_INFO,"connection:%d,characteristic:%d -->", connection, 14);
	uint16_t v_len ;
	/**> TODO : FIND THIS ATTRIBUTE */
	sl_bt_gatt_server_send_characteristic_notification(connection, characteristics[WIFI_CONFIG_GW].handle, len, (const uint8_t*)data, &v_len);
	return 0;
}
int gk_server_notify_battery(char*data,int len)
{
	int send_len=0;
	printf("battery:%d\n",battery++);
	if(connection != -1)
		sl_bt_gatt_server_send_characteristic_notification(connection,characteristics[BATTERY_DEVICE].handle,sizeof(battery),&battery,&send_len);
}

int gk_server_notify_attribute(char *mac, char *service_uuid, int slen, char *attr_uuid, int alen, int enable) {


	return 0;
}

int gk_register(stGk_evt_t* cbs)
{
	gk_evt = *cbs;
	return 0;
}

int gk_set_beacon_adv_data(char* data, int length)
{
	if (length > sizeof(gk.bcnBeaconAdvData) ) {
		return -1;
	}

	memcpy(gk.bcnBeaconAdvData, data, length);
	gk.bcnBeaconAdvDataLength = length;
	return 0;
}

int gk_set_beacon_adv_rsp_data(char* data, int length)
{
	if (length > sizeof(gk.bcnBeaconAdvRspData) ) {
		return -1;
	}

	memcpy(gk.bcnBeaconAdvRspData, data, length);
	gk.bcnBeaconAdvRspDataLength = length;
	return 0;
}


/////////////////////////////////////////////////////////////////////////////////////////////////////
//response and event
typedef struct stGeckoRspEvtHandler {
	int id;
	int (*handler)(int id, char *buf, int len);
} stGeckoRspEvtHandler_t;

int evt_rst_handler(int id, char *buf, int len);
int rsp_hello_handler(int id, char *buf, int len);
int evt_gatt_procedure_completed_handler(int id, char *buf, int len);
int rsp_le_gap_start_advertising(int id, char *buf, int len);
int evt_gatt_server_attribute_value(int id, char *buf, int len);
int evt_le_connection_closed(int id, char *buf, int len);
int rsp_le_gap_stop_advertising(int id, char *buf, int len);
int rsp_le_gap_set_advertising_data(int id, char *buf, int len);
int evt_le_connection_opened(int id, char *buf, int len);
int cmd_gatt_server_send_characteristic_notification(int id, char *buf, int len);
int evt_gatt_server_characteristic_status(int id, char *buf, int len);
int evt_le_gap_scan_response_handler(int id, char *buf, int len);
int rsp_get_bt_address_handler(int id, char *buf, int len);
int rsp_set_bt_address_handler(int id, char *buf, int len);
int evt_le_gap_connection_parameters_handler(int id, char *buf, int len);
int evt_le_gap_connection_phy_status_handler(int id, char *buf, int len);
int cmd_gattdb_new_session_handler(int id, char *buf, int len);
int rsp_cmd_gattdb_add_server_handler(int id, char *buf, int len);
int rsp_cmd_gattdb_add_uuid16_characteristic_handler(int id, char *buf, int len);
int rsp_cmd_gattdb_start_service_handler(int id, char *buf, int len);
int rsp_cmd_gattdb_commit_handler(int id, char *buf, int len);
int rsp_cmd_advertiser_create_handler(int id, char *buf, int len);
int rsp_cmd_system_set_tx_power_handler(int id, char *buf, int len);

static stGeckoRspEvtHandler_t grehs[] = {
	{sl_bt_evt_system_boot_id,											evt_rst_handler},
	{sl_bt_rsp_system_get_identity_address_id,							rsp_get_bt_address_handler},
	{sl_bt_rsp_system_set_identity_address_id,							rsp_set_bt_address_handler},
	{sl_bt_rsp_system_hello_id,											rsp_hello_handler},	
	{sl_bt_evt_connection_closed_id, 									evt_le_connection_closed},
	{sl_bt_evt_connection_opened_id,		 							evt_le_connection_opened},
	{sl_bt_rsp_connection_set_parameters_id,							evt_le_gap_connection_parameters_handler},
	{sl_bt_evt_connection_phy_status_id,								evt_le_gap_connection_phy_status_handler},
	{sl_bt_cmd_advertiser_stop_id, 										rsp_le_gap_stop_advertising},
	{sl_bt_cmd_advertiser_start_id,										rsp_le_gap_start_advertising},
	{sl_bt_cmd_advertiser_set_data_id, 									rsp_le_gap_set_advertising_data},
	{sl_bt_cmd_gatt_server_send_characteristic_notification_id, 		cmd_gatt_server_send_characteristic_notification},
	{sl_bt_evt_gatt_server_attribute_value_id, 							evt_gatt_server_attribute_value},
	{sl_bt_evt_gatt_server_characteristic_status_id,  					evt_gatt_server_characteristic_status},
	{sl_bt_cmd_gattdb_new_session_id,									cmd_gattdb_new_session_handler},
	{sl_bt_cmd_gattdb_add_service_id,									rsp_cmd_gattdb_add_server_handler},
	{sl_bt_cmd_gattdb_add_uuid16_characteristic_id,						rsp_cmd_gattdb_add_uuid16_characteristic_handler},
	{sl_bt_cmd_gattdb_start_service_id,									rsp_cmd_gattdb_start_service_handler},
	{sl_bt_cmd_gattdb_commit_id,										rsp_cmd_gattdb_commit_handler},
	{sl_bt_cmd_advertiser_create_set_id,								rsp_cmd_advertiser_create_handler},
	{sl_bt_cmd_system_set_tx_power_id,									rsp_cmd_system_set_tx_power_handler}
};

stGeckoRspEvtHandler_t *gk_rsp_evt_handler_search(int id) {
	int cnt = sizeof(grehs)/sizeof(grehs[0]);
	int i = 0;
	for (i = 0; i < cnt; i++) {
		stGeckoRspEvtHandler_t *greh = &grehs[i];
		if (greh->id == id) {
			return greh;
		}
	}
	return NULL;
}

static int gk_rsp_evt_handler(sl_bt_msg_t *pkt) {
	stGeckoRspEvtHandler_t *greh = gk_rsp_evt_handler_search(SL_BT_MSG_ID(pkt->header));
	if (greh == NULL) {
		gk_log(GK_LOG_INFO,"no hanlder for %s(%08X)", gecko_id2string(SL_BT_MSG_ID(pkt->header)), SL_BT_MSG_ID(pkt->header));
		return -1;
	}	

	return greh->handler(SL_BT_MSG_ID(pkt->header), (char *)&pkt->data, SL_BT_MSG_LEN(pkt->header));
}



int evt_rst_handler(int id, char *buf, int len) {
	sl_bt_evt_system_boot_t *rsp = (sl_bt_evt_system_boot_t*)buf;
	gk_log(GK_LOG_INFO,"ver %X.%X.%X build %X bootload %04X %04X %04X", rsp->major, rsp->minor, rsp->patch, rsp->build, rsp->bootloader, rsp->hw, rsp->hash);
	
	bd_addr bt_mac = {};
	short min_out = 0;
	short max_out = 0;
	sl_bt_system_set_tx_power(80, 80, &min_out, &max_out);
	
	bt_mac.addr[5] = gk.u_mac[0];
	bt_mac.addr[4] = gk.u_mac[1];
	bt_mac.addr[3] = gk.u_mac[2];
	bt_mac.addr[2] = gk.u_mac[3];
	bt_mac.addr[1] = gk.u_mac[4];
	bt_mac.addr[0] = gk.u_mac[5];
	gk_log(GK_LOG_INFO,"bd_addr:%02X:%02X:%02X:%02X:%02X:%02X", 	bt_mac.addr[5]&0xff,
															bt_mac.addr[4]&0xff,
															bt_mac.addr[3]&0xff,
															bt_mac.addr[2]&0xff,
															bt_mac.addr[1]&0xff,
															bt_mac.addr[0]&0xff);

	/* jio@2023-12-11 11:01 原因：加入软件版本获取 */
	if (gk_evt.on_boot != NULL) {
		gk_evt.on_boot(rsp->major, rsp->minor, rsp->patch, rsp->build);
	}
	sl_bt_system_set_identity_address(bt_mac, 0);
		usleep(50000);
	//schedue_add(&gk_sd_task, 50, gk_sd_get_bt_address, 0);
	gk_sd_get_bt_address(0);
	return 0;
}

int rsp_hello_handler(int id, char *buf, int len) {
	gk_log(GK_LOG_INFO," ");
	if (gk_evt.hello_rsp_cb != NULL) {
		gk_evt.hello_rsp_cb();
	}
	b_status = BLUFI_HELLO_SUCC;
	return 0;
}

int evt_gatt_procedure_completed_handler(int id, char *buf, int len) {
	gk_log(GK_LOG_INFO," ");

	/**> 
	 * struct gecko_msg_gatt_procedure_completed_evt_t *evt = (struct gecko_msg_gatt_procedure_completed_evt_t*)buf;
	 * gk_log(GK_LOG_INFO,"connection:%02X, result:0x%x", evt->connection, evt->result);
	 */

	return 0;
}

int rsp_cmd_system_set_tx_power_handler(int id, char *buf, int len){
	sl_bt_cmd_system_set_tx_power_t *rsp = (sl_bt_cmd_system_set_tx_power_t *)buf;
	gk_log(GK_LOG_INFO,"rsp_cmd_system_set_tx_power_handler max %u min %u ", rsp->max_power, rsp->min_power);
	
	return 0;
}

int rsp_le_gap_start_advertising(int id, char *buf, int len) {
	sl_bt_rsp_advertiser_start_t *rsp = (sl_bt_rsp_advertiser_start_t*)buf;
	gk_log(GK_LOG_INFO,"start advertising result %04X", rsp->result);
	if(rsp->result == 0x00){
		if (gk_evt.beacon_start_cb != NULL) {
			gk_evt.beacon_start_cb(rsp->result);
	}
	}else{
			usleep(20000);
		//schedue_add(&gk_sd_task, 20, gk_sd_start_adv_func, 0);
		gk_sd_start_adv_func();
	}
	return 0;
}

int rsp_le_gap_stop_advertising(int id, char *buf, int len) {
	sl_bt_rsp_advertiser_stop_t *rsp = (sl_bt_rsp_advertiser_stop_t*)buf;
	gk_log(GK_LOG_INFO,"stop advertising result %04X", rsp->result);

	if (gk_evt.on_beacon_stop) {
		gk_evt.on_beacon_stop(rsp->result);
	}
	return 0;
}

int rsp_le_gap_set_advertising_data(int id, char *buf, int len) {
	sl_bt_cmd_advertiser_set_data_t *rsp = (sl_bt_cmd_advertiser_set_data_t*)buf;
	gk_log(GK_LOG_INFO,"handle %u packet_type %u adv_data len %u", rsp->handle, rsp->packet_type, rsp->adv_data.len);
	return 0;
}

int rsp_get_bt_address_handler(int id, char *buf, int len){
	sl_bt_rsp_system_get_identity_address_t *rsp = (sl_bt_rsp_system_get_identity_address_t *)buf;
	gk_log(GK_LOG_INFO,"bd_addr:%02X:%02X:%02X:%02X:%02X:%02X \n", 	rsp->address.addr[5]&0xff,
															rsp->address.addr[4]&0xff,
															rsp->address.addr[3]&0xff,
															rsp->address.addr[2]&0xff,
															rsp->address.addr[1]&0xff,
															rsp->address.addr[0]&0xff);
	char bt_addr[] = {
						rsp->address.addr[5]&0xff,
						rsp->address.addr[4]&0xff,
						rsp->address.addr[3]&0xff,
						rsp->address.addr[2]&0xff,
						rsp->address.addr[1]&0xff,
						rsp->address.addr[0]&0xff
					};
	gk_sd_set_adv_func(bt_addr);
//	char str_mac[32] = {};
//	gk_log(GK_LOG_INFO,"mac to str %s", util_mac2str(bt_addr, str_mac));
//	blufi_product_set_mac(str_mac);
	
	return 0;
}


int rsp_set_bt_address_handler(int id, char *buf, int len){
	sl_bt_rsp_system_set_identity_address_t *rsp = (sl_bt_rsp_system_set_identity_address_t *)buf;
	gk_log(GK_LOG_INFO,"rsp_set_bt_address_handler ret %u \n", rsp->result);
	
	return 0;
}

static service_index_t ser_i ;
int cmd_gattdb_new_session_handler(int id, char *buf, int len){
	printf("cmd_gattdb_new_session_handler:id:%d",id);
	sl_bt_rsp_gattdb_new_session_t *rsp = (sl_bt_rsp_gattdb_new_session_t *)buf;
	gk_log(GK_LOG_INFO,"cmd_gattdb_new_session_handler session %u result %u \n", rsp->session, rsp->result);
	gattdb_session = rsp->session;
	 // Add services
	 ser_i = (service_index_t)2;
	 app_gattdb_add_service(gattdb_session, &services[ser_i]);

	 //ser_i = (service_index_t)3;
	 //app_gattdb_add_service(gattdb_session, &services[ser_i]);
	 
	return 0;
}

static characteristic_index_t cha_i ;
int rsp_cmd_gattdb_add_server_handler(int id, char *buf, int len){
	sl_bt_rsp_gattdb_add_service_t *rsp = (sl_bt_rsp_gattdb_add_service_t *)buf;
	gk_log(GK_LOG_INFO,"sl_bt_cmd_gattdb_add_service result %X  service %X \n", rsp->result, rsp->service);
	services[ser_i].handle = rsp->service;
	printf("ser_i:%d\n",ser_i);
	ser_i++;
	if(ser_i < SERVICES_COUNT){
		app_gattdb_add_service(gattdb_session, &services[ser_i]);
		return 0;
	}

	cha_i = (characteristic_index_t)4;
	// Add characteristics
	app_gattdb_add_characteristic(gattdb_session, &characteristics[cha_i]);
	 
	return 0;
}

int rsp_cmd_gattdb_add_uuid16_characteristic_handler(int id, char *buf, int len){
/*
	uint16_t			session;
	uint16_t			service;
	uint16_t			property;
	uint16_t			security;
	uint8_t 			flag;
	sl_bt_uuid_16_t 	uuid;
	uint8_t 			value_type;
	uint16_t			maxlen;
	byte_array			value;
*/
	sl_bt_rsp_gattdb_add_uuid16_characteristic_t *rsp = (sl_bt_rsp_gattdb_add_uuid16_characteristic_t *)buf;
	 gk_log(GK_LOG_INFO,"rsp_cmd_gattdb_add_uuid16_characteristic_handler result %X	characteristic %X \n", rsp->result, rsp->characteristic);
	characteristics[cha_i].handle = rsp->characteristic;
	cha_i++;
	if(cha_i < CHARACTERISTICS_COUNT){
		app_gattdb_add_characteristic(gattdb_session, &characteristics[cha_i]);
		return 0;
	}

	ser_i = (service_index_t)2;
	 // Start services and child characteristics
	sl_bt_gattdb_start_service(gattdb_session, services[ser_i].handle);
	return 0;
}

int rsp_cmd_gattdb_start_service_handler(int id, char *buf, int len){
	sl_bt_rsp_gattdb_start_service_t *rsp = (sl_bt_rsp_gattdb_start_service_t *)buf;
	gk_log(GK_LOG_INFO,"rsp_cmd_gattdb_start_service_handler result %X  \n", rsp->result);
	ser_i++;
	if(ser_i < SERVICES_COUNT){
		sl_bt_gattdb_start_service(gattdb_session, services[ser_i].handle);
		return 0;
	}
	
	// Commit changes
	sl_bt_gattdb_commit(gattdb_session);
	
	return 0;
}

int rsp_cmd_gattdb_commit_handler(int id, char *buf, int len){
	sl_bt_rsp_gattdb_commit_t *rsp = (sl_bt_rsp_gattdb_commit_t *)buf;
	gk_log(GK_LOG_INFO,"rsp_cmd_gattdb_commit_handler result %X  \n", rsp->result);

	sl_bt_advertiser_create_set(&advertising_set_handle);

	return 0;
}

int rsp_cmd_advertiser_create_handler(int id, char *buf, int len){
	sl_bt_rsp_advertiser_create_set_t *rsp = (sl_bt_rsp_advertiser_create_set_t *)buf;
	gk_log(GK_LOG_INFO,"rsp_cmd_advertiser_create_handler result %u handle %u \n", rsp->result, rsp->handle);
	advertising_set_handle = rsp->handle;
	uint8_t bcnBeaconAdvData[] = {
		0x02, 0x01, 0x06,
		0x13, 0xff,
		0x00, 0x00,
		'd','u','s','u','n', //identify
		0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //mac
		0x00, 0x30, //pid
		0x01, //If you want a one-click distribution network with gateway, set it to 1.
		0x01, //version
		0x02, //type, 1->common ble, 2->doul ble, 3->doul mesh, 4->android screen ble
		0x05, 0x12, 0x00, 0x06, 0x0c, 0x80
	};

	memcpy(&bcnBeaconAdvData[12], g_bt_addr, /*sizeof(rsp->address)*/6);

	if (gk.bcnBeaconAdvDataLength > 0) {
		sl_bt_advertiser_set_data(advertising_set_handle, 0, gk.bcnBeaconAdvDataLength, gk.bcnBeaconAdvData);
	} else {
		sl_bt_advertiser_set_data(advertising_set_handle, 0, sizeof(bcnBeaconAdvData), bcnBeaconAdvData);
	}
	usleep(200000);
	//schedue_add(&gk_sd_task, 200, gk_sd_set_adv_rsp_func, 0);
	gk_sd_set_adv_rsp_func();
	return 0;
}

int evt_le_gap_scan_response_handler(int id, char *buf, int len) {
/**>
struct gecko_msg_le_gap_scan_response_evt_t *evt = (struct gecko_msg_le_gap_scan_response_evt_t *)buf;
	
	gk_log(GK_LOG_INFO,"rssi:%02X, packet_type:%02X, bd_addr:%02X:%02X:%02X:%02X:%02X:%02X, addr_type:%02X, bonding:%02X",
						evt->rssi&0xff, 
						evt->packet_type&0xff, 
						evt->address.addr[5]&0xff, 
						evt->address.addr[4]&0xff, 
						evt->address.addr[3]&0xff, 
						evt->address.addr[2]&0xff, 
						evt->address.addr[1]&0xff, 
						evt->address.addr[0]&0xff, 
						evt->address_type&0xff, 
						evt->bonding&0xff);

	BLUFI_LOG_PRIT_hex("data:", evt->data.data, evt->data.len);
	gk_log(GK_LOG_INFO,"\n\n");
*/
	return 0;
}

int evt_gatt_server_attribute_value(int id, char *buf, int len) {
	sl_bt_evt_gatt_server_attribute_value_t *evt = (sl_bt_evt_gatt_server_attribute_value_t*)buf;
	gk_log(GK_LOG_INFO,"connection:%d, attribute:%04X, att_opcode:%02X, offset:%04X", 
			evt->connection&0xff, evt->attribute&0xffff, evt->att_opcode&0xff, evt->offset&0xffff);
	//BLUFI_LOG_PRIT_hex("write:", evt->value.data, evt->value.len);

	if (1 || (evt->attribute&0xffff) == (0xaa01&0xffff)) {
		if (gk_evt.on_data_in != NULL) {
			gk_evt.on_data_in((char *)evt->value.data, evt->value.len&0xff);
		}
	}
	return 0;
}

int evt_le_gap_connection_parameters_handler(int id, char *buf, int len) {
	gk_log(GK_LOG_INFO," ");
	sl_bt_evt_connection_parameters_t *evt = (sl_bt_evt_connection_parameters_t *)buf;

	gk_log(GK_LOG_INFO,"connection:%02X, interval:%04X, latency:%04X, timeout:%04X, security_mode:%02X, txsize:%04X",
		evt->connection, evt->interval, evt->latency, evt->timeout, evt->security_mode, evt->txsize);

	return 0;
}

int evt_le_gap_connection_phy_status_handler(int id, char *buf, int len) {
	gk_log(GK_LOG_INFO," ");
	sl_bt_evt_connection_phy_status_t *evt = (sl_bt_evt_connection_phy_status_t *)buf;
	gk_log(GK_LOG_INFO,"connection:%02X, phy:%02X", evt->connection, evt->phy);
	return 0;
}
int evt_gatt_server_characteristic_status(int id, char *buf, int len){

	printf("id:%d\n",id);
	sl_bt_evt_gatt_server_characteristic_status_t *evt = (sl_bt_evt_gatt_server_characteristic_status_t*)buf;
	gk_log(GK_LOG_INFO," ");
	if (evt->status_flags == 0x01) {   
		//evt->data.evt_gatt_server_characteristic_status.characteristic
		if (evt->client_config_flags == 0x00) {    
			gk_log(GK_LOG_INFO,"notify Disabled");
			//notifyEnabled = false;   
		}else{      
			//notifyEnabled = true;   
			gk_log(GK_LOG_INFO,"notify Enabled");
		}
	}

	return 0;
}

int evt_le_connection_closed(int id, char *buf, int len) {
	sl_bt_evt_connection_closed_t *evt = (sl_bt_evt_connection_closed_t*)buf;
	gk_log(GK_LOG_INFO,"connection:%d closed, reason:%04X", evt->connection, evt->reason&0xffff);
		
	connection = -1;
	if (gk_evt.on_disconnect != NULL) {
		gk_evt.on_disconnect();
	}
	return 0;
}

int evt_le_connection_opened(int id, char *buf, int len) {
	sl_bt_evt_connection_opened_t *evt = (sl_bt_evt_connection_opened_t*)buf;	
	connection = evt->connection;
	gk_log(GK_LOG_INFO,"connection:%d", connection);
	return 0;
}

int cmd_gatt_server_send_characteristic_notification(int id, char *buf, int len) {
	sl_bt_rsp_gatt_server_send_characteristic_notification_t *rsp =  (sl_bt_rsp_gatt_server_send_characteristic_notification_t *)buf;
	gk_log(GK_LOG_INFO,"result:%04X(%d), send_len:%04X", rsp->result, rsp->result&0xffff, rsp->sent_len&0xffff);

	return 0;
}
